﻿using CaseManagerLibrary.DB.SQLite;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CaseManagerLibrary.Log
{
    public class SQLiteLog : ILog
    {
        private Queue<LogData> logBuffer = new Queue<LogData>();
        private Thread writeThread;

        private const string blank = "                         ";
        public bool Logging { get; set; }
        public string LogPath { get; set; }
        public bool BringToFront { get; set; }
        public int Left { get; set; }
        public int Top { get; set; }
        public bool Writing { get; private set; }

        private string logFileName = "";
        private string sqlFile = "";
        private string ProductId = "";
        private string SN = "";
        private SQLiteHelper sqlite = new SQLiteHelper();

        public SQLiteLog(string logPath, string productId, string sn, string logFile = "psd")
        {
            Left = 0;
            Top = 0;
            LogPath = logPath;
            ProductId = productId;
            SN = sn;
            Writing = false;
            logFileName = logFile;

            Logging = CreateFile();

            if (Logging)
            {
                sqlite.FileName = sqlFile;
            }

            writeThread = new Thread(new ThreadStart(WriteFile));
            writeThread.Start();
        }

        private bool CreateFile()
        {
            if (!System.IO.Directory.Exists(LogPath))
            {
                System.IO.Directory.CreateDirectory(LogPath);
            }

            sqlFile = System.IO.Path.Combine(LogPath, logFileName + DateTime.Now.ToString("yyyy-MM") + ".log");

            if (!System.IO.File.Exists(sqlFile))
            {
                if (sqlite.Create(sqlFile))
                {
                    return sqlite.CreateTable<LogData>(sqlFile);
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return true;
            }
        }

        private void WriteFile()
        {
            while (Logging)
            {
                if (logBuffer.Count > 0)
                {
                    if (CreateFile())
                    {
                        var conn = sqlite.Open();

                        if (conn != null)
                        {
                            while (logBuffer.Count > 0)
                            {
                                Writing = true;

                                LogData data = logBuffer.Peek();

                                try
                                {
                                    sqlite.Insert<LogData>(conn, data);
                                    logBuffer.Dequeue();
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine("SQLiteLog write log error: " + ex.Message + (ex.InnerException == null ? "" : ex.InnerException.Message));
                                }
                            }

                            sqlite.Close(conn);
                        }
                    }
                    else
                    {
                        string errorfile = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "PSD", "LOG", "logerror.txt");

                        var sw = System.IO.File.AppendText(errorfile);
                        sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 创建日志文件失败");
                        sw.Close();
                    }
                }

                Writing = false;

                Thread.Sleep(1000);
            }
        }

        public void Close()
        {
            while (Writing)
            {
                Logging = true;
                Thread.Sleep(100);
            }
            Logging = false;
        }

        private void CreateLog(string type, string text)
        {
            LogData data = new LogData();
            data.log_id = Guid.NewGuid().ToString();
            data.log_time = DateTime.Now;
            data.log_type = type;
            data.log_content = text;
            data.product_id = this.ProductId;
            data.sn = this.SN;

            logBuffer.Enqueue(data);
        }

        public void Error(string text)
        {
            try
            {
                CreateLog("ERROR", text);
            }
            catch (Exception ex)
            { }
        }

        public void Info(string text)
        {
            try
            {
                CreateLog("INFO", text);
            }
            catch (Exception ex)
            { }
        }

        public void Log(string text)
        {
            try
            {
                CreateLog("LOG", text);
            }
            catch (Exception ex)
            { }
        }

        public void MC()
        {
            try
            {
                //logBuffer.Enqueue("MC>");
            }
            catch (Exception ex)
            { }
        }

        public void NewLine()
        {
            try
            {
                //logBuffer.Enqueue("");
            }
            catch (Exception ex)
            { }
        }

        public void Text(string text)
        {
            try
            {
                CreateLog("TEXT", text);
            }
            catch (Exception ex)
            { }
        }
    }
}
